package com.semlab.client.app.gin;

import com.google.gwt.core.client.GWT;
import com.google.gwt.event.shared.EventBus;
import com.google.gwt.event.shared.SimpleEventBus;
import com.google.gwt.inject.client.AbstractGinModule;
import com.google.gwt.place.shared.Place;
import com.google.gwt.place.shared.PlaceController;
import com.google.gwt.place.shared.PlaceHistoryHandler;
import com.google.gwt.place.shared.PlaceHistoryMapper;
import com.google.inject.Inject;
import com.google.inject.Provider;
import com.google.inject.Singleton;
import com.semlab.client.fwk.ap.ActivityRegistry;
import com.semlab.client.fwk.ap.AppPlaceHistoryMapper;
import com.semlab.client.fwk.ap.DefaultActivityRegistry;
import com.semlab.client.fwk.ap.DefaultPlaceController;
import com.semlab.client.req.RequestFactory;


public class SystemModule extends AbstractGinModule {
	
	@Override
	protected void configure() {
		bind(EventBus.class).to(SimpleEventBus.class).in(Singleton.class);
		bind(PlaceController.class).toProvider(PlaceControllerProvider.class).in(Singleton.class);
		bind(PlaceHistoryHandler.class).toProvider(PlaceHistoryHandlerProvider.class).in(Singleton.class);
		bind(DefaultActivityRegistry.class).asEagerSingleton();
		bind(ActivityRegistry.class).to(DefaultActivityRegistry.class).asEagerSingleton();
		bind(PlaceHistoryMapper.class).to(AppPlaceHistoryMapper.class).in(Singleton.class);
		bind(RequestFactory.class).toProvider(RequestFactoryProvider.class).in(Singleton.class);
	}

	public static class RequestFactoryProvider implements Provider<RequestFactory> {

		private final EventBus eventBus;

		@Inject
		public RequestFactoryProvider(EventBus eventBus) {
			this.eventBus = eventBus;
		}

		@Override
		public RequestFactory get() {
			RequestFactory factory = GWT.create(RequestFactory.class);
			factory.initialize(eventBus);
			return factory;
		}

	}
	
	public static class PlaceControllerProvider implements Provider<PlaceController> {

		private final EventBus eventBus;

		@Inject
		public PlaceControllerProvider(EventBus eventBus) {
			this.eventBus = eventBus;
		}

		public PlaceController get() {
			return new DefaultPlaceController(eventBus){
				@Override
				protected boolean isPlaceChangeAllowed(Place newPlace) {
					return true;
				}
			};
		}
	}
	
	public static class PlaceHistoryHandlerProvider implements Provider<PlaceHistoryHandler> {
		
		private PlaceHistoryMapper placeHistoryMapper;

		@Inject
		public PlaceHistoryHandlerProvider(PlaceHistoryMapper placeHistoryMapper) {
			this.placeHistoryMapper = placeHistoryMapper;
		}
		
		public PlaceHistoryHandler get() {
			return new PlaceHistoryHandler(placeHistoryMapper);
		}
	}

}
